/**
 * VYPe11 Project
 * VYPe11 language compiler.
 * Authors: Jozef Lang (xlangj01), 
 * 			Zoltan Zemko (xzemko01)
 * 2011
 */
package cz.vutbr.fit.VYPe.team18.VYPe11.nodes.expression.bracket;

import java.io.IOException;

import cz.vutbr.fit.VYPe.team18.VYPe11.exception.SematicException;
import cz.vutbr.fit.VYPe.team18.VYPe11.nodes.data_type.DataType;
import cz.vutbr.fit.VYPe.team18.VYPe11.nodes.data_type.DataTypeNode;
import cz.vutbr.fit.VYPe.team18.VYPe11.nodes.expression.ExpressionNode;

public class CastOperatorNode extends ExpressionNode {
	private DataTypeNode castType;
	private ExpressionNode expression;
	
	public CastOperatorNode(DataTypeNode castType, 
			ExpressionNode expression) {
		this.castType=castType;
		this.expression=expression;
	}

	public DataTypeNode getCastTypeNode() {
		return castType;
	}

	public ExpressionNode getExpression() {
		return expression;
	}
	
	public DataType getType() throws SematicException {
		DataType cdt=castType.getType();		
		DataType dt=this.expression.getType();	
		
		if(cdt==dt
			|| (cdt==DataType.INT && dt==DataType.SHORT)	// short -> int
			|| (cdt==DataType.CHAR && dt==DataType.STRING) 	// string -> char
			|| (cdt==DataType.SHORT 						// int -> short
				&& (dt==DataType.INT || dt==DataType.CHAR))	// char -> short	
			)
		{
			return cdt;
		}
		else
		{
			throw new SematicException("Casting failed.");
		}
	}
	
	@Override
	public void generateTAC() throws IOException {
		expression.generateTAC();
		int i=tacCounter.getTermIndex()-1;
		
		DataType cdt=castType.getType();		
		DataType dt;
		try {
			dt = this.expression.getType();
		} catch (SematicException e) {
			e.printStackTrace();
			return;
		}
		
		if(cdt==DataType.INT && dt==DataType.SHORT)
		{
			writeTAC("ShortToInt", "_t"+i, "", "_t"+tacCounter.getNextTermIndex());
		}
		else if(cdt==DataType.INT && dt==DataType.SHORT)
		{
			writeTAC("StringToChar", "_t"+i, "", "_t"+tacCounter.getNextTermIndex());
		}
		else if(cdt==DataType.INT && dt==DataType.SHORT)
		{
			writeTAC("IntToShort", "_t"+i, "", "_t"+tacCounter.getNextTermIndex());
		}
		else if(cdt==DataType.INT && dt==DataType.CHAR)
		{
			writeTAC("IntToChar", "_t"+i, "", "_t"+tacCounter.getNextTermIndex());
		}
	}
	
}
